package olga.gorbatiuk.perdep.logger.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import olga.gorbatiuk.perdep.logger.Journal;
import olga.gorbatiuk.perdep.logger.exceptions.IllegalRangeException;
import olga.gorbatiuk.perdep.logger.record.Record;
import olga.gorbatiuk.perdep.logger.record.comparator.ByDateAndImportanceComparator;
import olga.gorbatiuk.perdep.logger.record.comparator.ByDateComparator;

public class CollectionJournal implements Journal {

    private List<Record> recordList;

    // private int size;
    // private int quantity;
    public CollectionJournal() {
        // this.size = 0;
        this.recordList = new ArrayList<Record>();
    }

    public CollectionJournal(CollectionJournal journal) {
        // this.size = journal.getSize();
        List<Record> newRecordList = new ArrayList<Record>();
        Collections.copy(newRecordList, journal.getRecordList());
        this.recordList = newRecordList;
    }

    @Override
    public void add(Record r) {
        recordList.add(r);
    }

    @Override
    public void add(Journal j) {
        if (j.getClass() == this.getClass()) {
            CollectionJournal otherCollectionJournal = (CollectionJournal) j;
            recordList.addAll(otherCollectionJournal.getRecordList());
        }
    }

    @Override
    public void remove(Record r) {
        recordList.remove(r);

    }

    @Override
    public Record get(int index) {
        return recordList.get(index);
    }

    @Override
    public void set(int index, Record record) {
        recordList.set(index, record);

    }

    @Override
    public void insert(int index, Record record) {
        recordList.add(index, record);

    }

    @Override
    public void remove(int index) {
        recordList.remove(index);

    }

    @Override
    public void remove(int fromIndex, int toIndex) throws IllegalRangeException {
        validateRange(fromIndex, toIndex);
        int recordsToRemove = toIndex - fromIndex + 1;
        for (int i = 0; i < recordsToRemove; i++) {
            recordList.remove(fromIndex);
        }
    }

    private void validateRange(int fromIndex, int toIndex) throws IllegalRangeException {
        if ((fromIndex < 0) || (toIndex < 0)) {
            throw new IllegalRangeException("Both indexes should be greater "
                    + "than zero, but your indexes are: " + fromIndex + " and " + toIndex + ".");
        }
        if ((fromIndex >= size()) || (toIndex >= size())) {
            throw new IllegalRangeException("Both indexes should be less "
                    + "than Journal length: " + size()
                    + ". But your indexes are: " + fromIndex + " and " + toIndex + ".");
        }
        if (fromIndex >= toIndex) {
            throw new IllegalRangeException("toIndex should be greater or equals than fromIndex.");
        }
    }

    @Override
    public void removeAll() {
        recordList.removeAll(recordList);
    }

    @Override
    public int size() {
        return recordList.size();
    }

    @Override
    public Journal filter(String s) {
        Journal newJournal = new CollectionJournal();
        for (int i = 0; i < size(); i++) {
            if (recordList.get(i).toString().contains(s)) {
                newJournal.add(recordList.get(i));
            }
        }
        return newJournal;
    }

    @Override
    public Journal filter(Date fromDate, Date toDate) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void sortByDate() {
        Collections.sort(recordList, new ByDateComparator());
    }

    @Override
    public void sortByImportanceDate() {
        Collections.sort(recordList, new ByDateAndImportanceComparator());

    }

    @Override
    public void sortByImportanceSourceDate() {
        // TODO Auto-generated method stub

    }

    @Override
    public void sortBySourceDate() {
        // TODO Auto-generated method stub

    }

    @Override
    public void printRecords() {
        for (Record record : recordList) {
            System.out.println(record.toString());
        }
    }

    public List<Record> getRecordList() {
        return recordList;
    }

    public void setRecordList(List<Record> recordList) {
        this.recordList = recordList;
    }

    // public int getSize() {
    // return size;
    // }
    //
    // public void setSize(int size) {
    // this.size = size;
    // }
    //
    // public int getQuantity() {
    // return quantity;
    // }
}
